package response

import (
	"net/http"

	"gitee.com/youkelike/zerror"
	"gitee.com/youkelike/ziam/zerrors"
	"gitee.com/youkelike/zlog"
	"github.com/gin-gonic/gin"
)

// 老版本，不好用
type ErrResponse struct {
	// Code defines the business error code.
	Code int `json:"code"`

	// Message contains the detail of this message.
	// This message is suitable to be exposed to external
	Message string `json:"message"`

	// Reference returns the reference document which maybe useful to solve this error.
	Reference string `json:"reference,omitempty"`
}

// 老版本，不好用
func Write(c *gin.Context, err error, data interface{}) {
	if err != nil {
		zlog.Errorw("%#+v", err)
		coder := zerrors.ParseCoder(err)
		c.JSON(coder.HTTPStatus(), ErrResponse{
			Code:      coder.Code(),
			Message:   coder.String(),
			Reference: coder.Reference(),
		})
	}

	c.JSON(http.StatusOK, data)
}

// 新版本，与 errorx 配合使用
type ErrorResponse struct {
	// 业务错误码
	Reason string `json:"reason,omitempty"`
	// 错误详情的描述信息
	Message string `json:"message,omitempty"`
	// 附带的元数据信息
	Metadata map[string]string `json:"metadata,omitempty"`
}

// 新版本，与 errorx 配合使用
// 它会根据是否发生错误，生成成功响应或标准化的错误响应.
func WriteResponse(c *gin.Context, data any, err error) {
	if err != nil {
		// 如果发生错误，生成错误响应
		errx := zerror.FromError(err) // 提取错误详细信息
		c.JSON(errx.Code, ErrorResponse{
			Reason:   errx.Reason,
			Message:  errx.Message,
			Metadata: errx.Metadata,
		})
		return
	}

	// 如果没有错误，返回成功响应
	c.JSON(http.StatusOK, data)
}
